package com.ll19.service.impl;

import java.util.Map;
import java.util.MissingResourceException;
import java.util.ResourceBundle;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jmock.Mockery;
import org.jmock.integration.junit4.JMock;
import org.jmock.integration.junit4.JUnit4Mockery;
import org.junit.runner.RunWith;

import com.ll19.util.ConvertUtil;

/**
 * A mock class for testing using JMock. This test class can be moved to the
 * test tree.
 * 
 * @author mraible
 */
@RunWith(JMock.class)
public abstract class BaseManagerMockTestCase {
	/**
	 * A logger
	 */
	protected final Log log = LogFactory.getLog(getClass());
	/**
	 * The resourceBundle
	 */
	protected ResourceBundle rb;
	/**
	 * The junit 4 context
	 */
	// Mockery类代表着所测试对象与之交互的测试环境.
	// Mockery类创建Mock对象并且检查设置在这些Mock对象上的期望值是否符合.
	// 通常, 把Mockery定义为成一个context名字的实例变量.

	// 创建Mock对象Creating Mock Objects
	// 例：创建一个类型为Turtle的模拟对象
	// Turtle turtle = context.mock(Turtle.class);

	// 如果上面两个变量不是实例变量,而是局部变量的话,那么应该在前面加上final修饰符,这样才能在Expection
	// block中进行访问.(Expection block下面会讲到）
	// 看来Mockery的实例并不会保存Mock对象的一个引用,不然也用不着加上final来扩展其生命周期了.
	// 还有给定的名称"turtle"只会影响turtle.toString()方法.当你调用toString()会输出这个名称.
	// 还有,mock方法只接受接口, 类和抽象类都不可以.

	protected Mockery context = new JUnit4Mockery();

	/**
	 * Default constructor will set the ResourceBundle if needed.
	 */
	public BaseManagerMockTestCase() {
		// Since a ResourceBundle is not required for each class, just
		// do a simple check to see if one exists
		String className = this.getClass().getName();

		try {
			rb = ResourceBundle.getBundle(className);
		} catch (MissingResourceException mre) {
			// log.debug("No resource bundle found for: " + className);
		}
	}

	/**
	 * Utility method to populate a javabean-style object with values from a
	 * Properties file
	 * 
	 * @param obj
	 *            the model object to populate
	 * @return Object populated object
	 * @throws Exception
	 *             if BeanUtils fails to copy properly
	 */
	protected Object populate(Object obj) throws Exception {
		// loop through all the beans methods and set its properties from
		// its .properties file
		Map map = ConvertUtil.convertBundleToMap(rb);

		BeanUtils.copyProperties(obj, map);

		return obj;
	}
}
